home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / C / Games / Xconq 7.1.0 / src / xconq-7.1.0 / kernel / side.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-07-07  |  59.8 KB  |  2,495 lines  |  [TEXT/R*ch]

  1. /* Sides in Xconq.
  2.    Copyright (C) 1987, 1988, 1989, 1991, 1992, 1993, 1994, 1995, 1996
  3.    Stanley T. Shebs.
  4.  
  5. Xconq is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2, or (at your option)
  8. any later version.  See the file COPYING.  */
  9.  
  10. /* This file implements sides and functionality relating to sides in
  11.    general. */
  12.  
  13. #include "conq.h"
  14.  
  15. #define checked_elev_at(x, y) (elevations_defined() ? elev_at(x, y) : 0)
  16.  
  17. static void init_visible_elevation PARAMS ((int x, int y));
  18. static void init_visible_elevation_2 PARAMS ((int x, int y));
  19. static void calc_visible_elevation PARAMS ((int x, int y));
  20. static void calc_visible_elevation_2 PARAMS ((int x, int y));
  21.  
  22. /* Head of the list of all sides. */
  23.  
  24. Side *sidelist;
  25.  
  26. /* Pointer to the side representing independence. */
  27.  
  28. Side *indepside;
  29.  
  30. /* Pointer to the last side of the list. */
  31.  
  32. Side *lastside;
  33.  
  34. /* Temporary used in many places. */
  35.      
  36. Side *tmpside;
  37.  
  38. /* The actual number of sides in a game.  This number never decreases;
  39.    sides no longer playing need to be around for recordskeeping purposes. */
  40.  
  41. int numsides;
  42.  
  43. /* Used to generate the id number of the side. */
  44.  
  45. int nextsideid;
  46.  
  47. /* Cached values of global vision vars. */
  48.  
  49. int all_see_all;
  50.  
  51. int any_los;
  52.  
  53. /* Pointer to buffer used for readable side description (for debugging). */
  54.  
  55. char *sidedesigbuf = NULL;
  56.  
  57. /* Pointer to the head of the list of players. */
  58.  
  59. Player *playerlist;
  60.  
  61. /* Pointer to the last player of the list, used to add players at end. */
  62.  
  63. Player *last_player;
  64.  
  65. /* The total number of players. */
  66.  
  67. int numplayers;
  68.  
  69. /* Use to generate the id number of each player. */
  70.  
  71. int nextplayerid;
  72.  
  73. char *playerdesigbuf = NULL;
  74.  
  75. /* The list of doctrine objects. */
  76.  
  77. Doctrine *doctrine_list;
  78.  
  79. Doctrine *last_doctrine;
  80.  
  81. int next_doctrine_id;
  82.  
  83. /* Init side machinery.   We always have an "independent" side hanging around;
  84.    it will be at the head of the list of sides, but normal side iteration
  85.    finesses this by starting from the second list element.  The independent
  86.    side is also a good placeholder for random stuff. */
  87.  
  88. void
  89. init_sides()
  90. {
  91.     /* Set up the list of sides. */
  92.     sidelist = lastside = (Side *) xmalloc(sizeof(Side));
  93.     /* The independent units' side will be the first one, is always created. */
  94.     indepside = sidelist;
  95.     /* Fill in some properties of the independents' side. */
  96.     indepside->name = "- indep -";
  97.     indepside->noun = "- indep -";
  98.     indepside->pluralnoun = "- indeps -";
  99.     indepside->adjective = "independent";
  100.     indepside->colorscheme = NULL;
  101.     /* By default, independent units are not identified by an emblem. */
  102.     /* A game design can set this appropriately if desired, however. */
  103.     indepside->emblemname = "none";
  104.     indepside->id = 0;
  105.     /* Put valid Lisp data into slots that need it. */
  106.     indepside->symbol = lispnil;
  107.     indepside->instructions = lispnil;
  108.     indepside->rawscores = lispnil;
  109.     indepside->aidata = lispnil;
  110.     indepside->uidata = lispnil;
  111.     /* The independent side is not counted in numsides. */
  112.     numsides = 0;
  113.     /* Regular side ids start at 1 and go up. */
  114.     nextsideid = 1;
  115.     /* Set up the list of players. */
  116.     playerlist = last_player = NULL;
  117.     numplayers = 0;
  118.     nextplayerid = 1;
  119.     /* Set up the player/side assignment array. */
  120.     assignments = (Assign *) xmalloc(MAXSIDES * sizeof(Assign));
  121.     /* Set up the list of doctrines. */
  122.     doctrine_list = last_doctrine = NULL;
  123.     next_doctrine_id = 1;
  124. }
  125.  
  126. /* Create an object representing a side. */
  127.  
  128. Side *
  129. create_side()
  130. {
  131.     int u;
  132.     Side *newside;
  133.  
  134.     if (numsides >= g_sides_max()) {
  135.     run_error("Cannot have more than %d sides total!", g_sides_max());
  136.     }
  137.     /* Allocate the side object proper. */
  138.     newside = (Side *) xmalloc(sizeof(Side));
  139.     /* Fill in various side slots.  Only those with non-zero/non-NULL
  140.        defaults need have anything done to them. */
  141.     newside->id = nextsideid++;
  142.     /* Always start sides IN the game. */
  143.     newside->ingame = TRUE;
  144.     /* Note that "everingame" is only set at the beginning of a turn. */
  145.     /* Set up the relationships with other sides. */
  146.     newside->knows_about = ALLSIDES; /* for now */
  147.     newside->trusts = (short *) xmalloc((g_sides_max() + 1) * sizeof(short));
  148.     newside->trades = (short *) xmalloc((g_sides_max() + 1) * sizeof(short));
  149.     /* Set up per-unit-type slots. */
  150.     newside->counts = (short *) xmalloc(numutypes * sizeof(short));
  151.     newside->tech = (short *) xmalloc(numutypes * sizeof(short));
  152.     newside->inittech = (short *) xmalloc(numutypes * sizeof(short));
  153.     newside->numunits = (short *) xmalloc(numutypes * sizeof(short));
  154.     newside->numlive = (short *) xmalloc(numutypes * sizeof(short));
  155.     for_all_unit_types(u) {
  156.     /* Start unit numbering at 1, not 0. */
  157.     newside->counts[u] = 1;
  158.     }
  159.     newside->priority = -1;
  160.     newside->autofinish = TRUE;
  161.     /* True by default, players should disable manually. */
  162.     newside->willingtosave = TRUE;
  163.     /* Put valid Lisp data into slots that need it. */
  164.     newside->symbol = lispnil;
  165.     newside->instructions = lispnil;
  166.     newside->rawscores = lispnil;
  167.     newside->aidata = lispnil;
  168.     newside->uidata = lispnil;
  169.     newside->startx = newside->starty = -1;
  170.     newside->gaincounts = (short *) xmalloc(numutypes * num_gain_reasons * sizeof(short));
  171.     newside->losscounts = (short *) xmalloc(numutypes * num_loss_reasons * sizeof(short));
  172.     newside->atkstats = (long **) xmalloc(numutypes * sizeof(long *));
  173.     newside->hitstats = (long **) xmalloc(numutypes * sizeof(long *));
  174.     /* Link in at the end of the list of sides. */
  175.     newside->next = NULL;
  176.     lastside->next = newside;
  177.     lastside = newside;
  178.     init_side_unithead(newside);
  179.     ++numsides;
  180.     return newside;
  181. }
  182.  
  183. /* To make the double links work, we have to have one pseudo-unit to serve
  184.    as a head.  This unit should not be seen by any outside code. */
  185.  
  186. void
  187. init_side_unithead(side)
  188. Side *side;
  189. {
  190.     if (side->unithead == NULL) {
  191.     side->unithead = create_bare_unit(0);
  192.     side->unithead->next = side->unithead;
  193.     side->unithead->prev = side->unithead;
  194.     }
  195. }
  196.  
  197. /* Quick check to see if we have units. */
  198.  
  199. /* This should be improved to not be fooled by dead units? */
  200.  
  201. int
  202. side_has_units(side)
  203. Side *side;
  204. {
  205.     return (side->unithead != NULL
  206.         && (side->unithead->next != side->unithead));
  207. }
  208.  
  209. /* Set up doctrine structures. */
  210.  
  211. void
  212. init_doctrine(side)
  213. Side *side;
  214. {
  215.     int u;
  216.  
  217.     if (side->default_doctrine == NULL) {
  218.     side->default_doctrine = new_doctrine(0);
  219.     side->default_doctrine->everaskside = TRUE;
  220.     side->default_doctrine->construction_run =
  221.       (short *) xmalloc (numutypes * sizeof(short));
  222.     }
  223.     if (side->udoctrine == NULL) {
  224.     /* Make each individual unit doctrine point to the generic doctrine by default. */
  225.     side->udoctrine = (Doctrine **) xmalloc(numutypes * sizeof(Doctrine *));
  226.     }
  227.     for_all_unit_types(u) {
  228.     if (side->udoctrine[u] == NULL)
  229.       side->udoctrine[u] = side->default_doctrine;
  230.     }
  231. }
  232.  
  233. void
  234. init_self_unit(side)
  235. Side *side;
  236. {
  237.     Unit *unit;
  238.  
  239.     if ((g_self_required() /* || side prop? */)
  240.     && side->self_unit == NULL) {
  241.     for_all_side_units(side, unit) {
  242.         if (u_can_be_self(unit->type)
  243.         && in_play(unit)
  244.         && completed(unit))
  245.           side->self_unit = unit;
  246.     }
  247.     }
  248. }
  249.  
  250. /* Initialize basic viewing structures for a side.  This happens when the
  251.    side is created (during/after reading but before synthesis). */
  252.  
  253. int
  254. init_view(side)
  255. Side *side;
  256. {
  257.     int terrainset = FALSE, t, u;
  258.  
  259.     /* (should check world validity/compatibility first?) */
  260.     if (side->terrview == NULL) {
  261.     side->terrview = malloc_area_layer(char);
  262.     if (!g_see_terrain_always()) {
  263.         side->terrviewdate = malloc_area_layer(short);
  264.         /* The terrview also holds the "have we seen it" flag, so it
  265.            must always be allocated, but the aux terrain view need not be. */
  266.         if (numcelltypes < numttypes) {
  267.         side->auxterrview = (char **) xmalloc(numttypes * sizeof(short *));
  268.         for_all_terrain_types(t) {
  269.             if (!t_is_cell(t)) {
  270.             side->auxterrview[t] = malloc_area_layer(char);
  271.             }
  272.         }
  273.         if (0 /* aux terrain seen separately from main terrain */) {
  274.             side->auxterrviewdate = (short **) xmalloc(numttypes * sizeof(short *));
  275.             for_all_terrain_types(t) {
  276.             if (!t_is_cell(t)) {
  277.                 side->auxterrviewdate[t] = malloc_area_layer(short);
  278.             }
  279.             }
  280.         }
  281.         }
  282.     }
  283.     } else {
  284.     terrainset = TRUE;
  285.     }
  286.     if (side->unitview == NULL) {
  287.     side->unitview = malloc_area_layer(short);
  288.     side->unitviewdate = malloc_area_layer(short);
  289. #if (MAXVIEWHISTORY > 0)
  290.     side->viewhistory[MAXVIEWHISTORY] = malloc_area_layer(long);
  291. #endif
  292.     }
  293.     /* Allocate weather view layers. */
  294.     if (any_temp_variation && !g_see_weather_always()) {
  295.     if (side->tempview == NULL) {
  296.         side->tempview = malloc_area_layer(short);
  297.     }
  298.     if (side->tempviewdate == NULL) {
  299.         side->tempviewdate = malloc_area_layer(short);
  300.     }
  301.     }
  302.     if (any_clouds && !g_see_weather_always()) {
  303.     if (side->cloudview == NULL) {
  304.         side->cloudview = malloc_area_layer(short);
  305.     }
  306.     if (side->cloudbottomview == NULL) {
  307.         side->cloudbottomview = malloc_area_layer(short);
  308.     }
  309.     if (side->cloudheightview == NULL) {
  310.         side->cloudheightview = malloc_area_layer(short);
  311.     }
  312.     if (side->cloudviewdate == NULL) {
  313.         side->cloudviewdate = malloc_area_layer(short);
  314.     }
  315.     }
  316.     if (any_wind_variation && !g_see_weather_always()) {
  317.     if (side->windview == NULL) {
  318.         side->windview = malloc_area_layer(short);
  319.     }
  320.     if (side->windviewdate == NULL) {
  321.         side->windviewdate = malloc_area_layer(short);
  322.     }
  323.     }
  324.     /* Allocate the vision coverage cache if needed. */
  325.     if (side->coverage == NULL) {
  326.     side->coverage = malloc_area_layer(short);
  327.     }
  328.     /* (should put this calc elsewhere?) */
  329.     any_los = FALSE;
  330.     for_all_unit_types(u) {
  331.     if (u_vision_bend(u) != 100) {
  332.         any_los = TRUE;
  333.         break;
  334.     }
  335.     }
  336.     /* Allocate vision altitude coverage if needed */
  337.     if (side->alt_coverage == NULL && any_los) {
  338.     side->alt_coverage = malloc_area_layer(short);
  339.     }
  340.     return terrainset;
  341. }
  342.  
  343. /* Calculate the centroid of all the starting units. */
  344.  
  345. void
  346. calc_start_xy(side)
  347. Side *side;
  348. {
  349.     int num = 0, sumx = 0, sumy = 0;
  350.     Unit *unit;
  351.  
  352.     for_all_side_units(side, unit) {
  353.     if (in_play(unit)) {
  354.         sumx += unit->x;  sumy += unit->y;
  355.         ++num;
  356.     }
  357.     }
  358.     if (num > 0) {
  359.     side->startx = wrapx(sumx / num);  side->starty = sumy / num;
  360.     }
  361. }
  362.  
  363. /* Given a side, get its "number", which is same as its "id". */
  364.  
  365. int
  366. side_number(side)
  367. Side *side;
  368. {
  369.     return (side == NULL ? indepside->id : side->id);
  370. }
  371.  
  372. /* The inverse function - given a number, figure out which side it is.
  373.    Returns NULL for independent side number and for any failures. */
  374.  
  375. Side *
  376. side_n(n)
  377. int n;
  378. {
  379.     Side *side;
  380.  
  381.     if (n < 1)
  382.       return NULL;
  383.     for_all_sides(side)
  384.       if (side->id == n)
  385.         return side;
  386.     return NULL;
  387. }
  388.  
  389. Side *
  390. find_side_by_name(str)
  391. char *str;
  392. {
  393.     Side *side;
  394.  
  395.     if (empty_string(str))
  396.       return NULL;
  397.     for_all_sides(side) {
  398.     if (!empty_string(side->name) && strcmp(side->name, str) == 0)
  399.       return side;
  400.     if (!empty_string(side->noun) && strcmp(side->noun, str) == 0)
  401.       return side;
  402.     if (!empty_string(side->pluralnoun) && strcmp(side->pluralnoun, str) == 0)
  403.       return side;
  404.     if (!empty_string(side->adjective) && strcmp(side->adjective, str) == 0)
  405.       return side;
  406.     }
  407.     return NULL;
  408. }
  409.  
  410. Side *
  411. parse_side_spec(str)
  412. char *str;
  413. {
  414.     int s;
  415.     char *reststr;
  416.  
  417.     if (isdigit(str[0])) {
  418.     s = strtol(str, &reststr, 10);
  419.     if (between(1, s, numsides)) {
  420.         return side_n(s);
  421.     }
  422.     } else {
  423.     return find_side_by_name(str);
  424.     }
  425.     return NULL;
  426. }
  427.  
  428. /* This is true when one side controls another. */
  429.  
  430. int
  431. side_controls_side(side, side2)
  432. Side *side, *side2;
  433. {
  434.     if (side == NULL || side2 == NULL)
  435.       return FALSE;
  436.     return (side == side2 || side2->controlled_by == side);
  437. }
  438.  
  439. short *max_control_ranges;
  440.  
  441. static int controller_here PARAMS ((int x, int y));
  442.  
  443. static int
  444. controller_here(x, y)
  445. int x, y;
  446. {
  447.     Unit *unit2;
  448.  
  449.     if (distance(x, y, tmpunit->x, tmpunit->y) < 2)
  450.       return FALSE;
  451.     for_all_stack(x, y, unit2) {
  452.     if (side_controls_unit(tmpside, unit2)
  453.         && probability(uu_control(unit2->type, tmpunit->type)))
  454.       return TRUE;
  455.     }
  456.     return FALSE;
  457. }
  458.  
  459. /* This is true if the given side may operate on the given unit. */
  460.  
  461. int
  462. side_controls_unit(side, unit)
  463. Side *side;
  464. Unit *unit;
  465. {
  466.     int dir, x1, y1;
  467.     Unit *unit2;
  468.  
  469.     if (side == NULL || unit == NULL)
  470.       return FALSE;
  471. #ifdef DESIGNERS
  472.     if (side->designer)
  473.       return TRUE;
  474. #endif
  475.     if (side_controls_side(side, unit->side)) {
  476.     /* should check if type is controllable and within control coverage */
  477.     /* should check if unit's cmdr is controlled */
  478.     /* The *unit* side must have the tech to use the unit, the controlling
  479.        side would have to actually take over the unit if it wants to use
  480.        its tech level to control the unit. */
  481.     if (unit->side != NULL && unit->side->tech[unit->type] < u_tech_to_use(unit->type))
  482.       return FALSE;
  483.     if (u_direct_control(unit->type) || unit == side->self_unit)
  484.       return TRUE;
  485.     /* Unit is not under direct control of the side; look for a controlled unit
  486.        that can control this unit. */
  487.     if (max_control_ranges == NULL) {
  488.         int u1, u2;
  489.  
  490.         max_control_ranges = (short *) xmalloc(numutypes * sizeof(short));
  491.         for_all_unit_types(u2) {
  492.         max_control_ranges[u2] = -1;
  493.         for_all_unit_types(u1) {
  494.             max_control_ranges[u2] =
  495.               max(max_control_ranges[u2], uu_control_range(u1, u2));
  496.         }
  497.         }
  498.     }
  499.     if (max_control_ranges[unit->type] >= 0) {
  500.         for_all_stack(unit->x, unit->y, unit2) {
  501.         if (unit != unit2
  502.             && side_controls_unit(side, unit2)
  503.             && probability(uu_control_at(unit2->type, unit->type)))
  504.           return TRUE;
  505.         }
  506.         /* (what about occupants that could be controllers?) */
  507.     }
  508.     if (max_control_ranges[unit->type] >= 1) {
  509.         for_all_directions(dir) {
  510.         if (interior_point_in_dir(unit->x, unit->y, dir, &x1, &y1)) {
  511.             for_all_stack(x1, y1, unit2) {
  512.             if (side_controls_unit(side, unit2)
  513.                 && probability(uu_control_adj(unit2->type, unit->type)))
  514.               return TRUE;
  515.             }
  516.         }
  517.         }
  518.     }
  519.     if (max_control_ranges[unit->type] >= 2) {
  520.         tmpside = side;
  521.         tmpunit = unit;
  522.         return search_around(unit->x, unit->y, max_control_ranges[unit->type],
  523.                      controller_here, &x1, &y1, 1);
  524.     }
  525.     }
  526.     /* (should add something for control for non-owned units?) */
  527.     return FALSE;
  528. }
  529.  
  530. /* This is true if the given side may examine the given unit. */
  531.  
  532. int
  533. side_sees_unit(side, unit)
  534. Side *side;
  535. Unit *unit;
  536. {
  537.     if (side == NULL || unit == NULL)
  538.       return FALSE;
  539. #ifdef DESIGNERS
  540.     if (side->designer)
  541.       return TRUE;
  542. #endif /* DESIGNERS */
  543.     if (side_controls_side(side, unit->side))
  544.       return TRUE;
  545.     return FALSE;
  546. }
  547.  
  548. int
  549. side_sees_image(side, unit)
  550. Side *side;
  551. Unit *unit;
  552. {
  553.     if (side == NULL || unit == NULL)
  554.       return FALSE;
  555. #ifdef DESIGNERS
  556.     if (side->designer)
  557.       return TRUE;
  558. #endif /* DESIGNERS */
  559.     if (all_see_all)
  560.       return TRUE;
  561.     if (side_controls_side(side, unit->side))
  562.       return TRUE;
  563.     if (in_area(unit->x, unit->y)
  564.     && side->coverage != NULL
  565.     && cover(side, unit->x, unit->y) > 0)
  566.       return TRUE;
  567.     return FALSE;
  568. }
  569.  
  570. int
  571. num_units_in_play(side, u)
  572. Side *side;
  573. int u;
  574. {
  575.     int num = 0;
  576.     Unit *unit;
  577.  
  578.     if (side != NULL && side->ingame) {
  579.       for_all_side_units(side, unit) {
  580.     if (unit->type == u
  581.         && in_play(unit)
  582.         && completed(unit))
  583.       ++num;
  584.       }
  585.     }
  586.     return num;
  587. }
  588.  
  589. int
  590. num_units_incomplete(side, u)
  591. Side *side;
  592. int u;
  593. {
  594.     int num = 0;
  595.     Unit *unit;
  596.  
  597.     if (side != NULL && side->ingame) {
  598.       for_all_side_units(side, unit) {
  599.     if (unit->type == u && alive(unit) && !completed(unit)) ++num;
  600.       }
  601.     }
  602.     return num;
  603. }
  604.  
  605. Unit *
  606. find_next_unit(side, prevunit)
  607. Side *side;
  608. Unit *prevunit;
  609. {
  610.     Unit *unit = NULL;
  611.  
  612.     if (side != NULL) {
  613.     if (prevunit == NULL)
  614.       prevunit = side->unithead;
  615.     for (unit = prevunit->next; unit != prevunit; unit = unit->next) {
  616.         if (is_unit(unit) && unit->id > 0
  617.         && alive(unit)
  618.         && inside_area(unit->x, unit->y)) {
  619.         return unit;
  620.         }
  621.     }
  622.     }
  623.     return NULL;
  624. }
  625.  
  626. Unit *
  627. find_prev_unit(side, nextunit)
  628. Side *side;
  629. Unit *nextunit;
  630. {
  631.     Unit *unit = NULL;
  632.  
  633.     if (side != NULL) {
  634.     if (nextunit == NULL) nextunit = side->unithead;
  635.     for (unit = nextunit->prev; unit != nextunit; unit = unit->prev) {
  636.         if (is_unit(unit) && unit->id > 0
  637.         && alive(unit)
  638.         && inside_area(unit->x, unit->y)) {
  639.         return unit;
  640.         }
  641.     }
  642.     }
  643.     return NULL;
  644. }
  645.  
  646. Unit *
  647. find_next_actor(side, prevunit)
  648. Side *side;
  649. Unit *prevunit;
  650. {
  651.     Unit *unit = NULL;
  652.  
  653.     if (side != NULL) {
  654.     if (prevunit == NULL) prevunit = side->unithead;
  655.     for (unit = prevunit->next; unit != prevunit; unit = unit->next) {
  656.         if (is_unit(unit) && unit->id > 0
  657.         && alive(unit)
  658.         && inside_area(unit->x, unit->y)
  659.         && (unit->act && unit->act->initacp)) {
  660.         return unit;
  661.         }
  662.     }
  663.     }
  664.     return NULL;
  665. }
  666.  
  667. Unit *
  668. find_prev_actor(side, nextunit)
  669. Side *side;
  670. Unit *nextunit;
  671. {
  672.     Unit *unit = NULL;
  673.  
  674.     if (side != NULL) {
  675.     if (nextunit == NULL)
  676.       nextunit = side->unithead;
  677.     for (unit = nextunit->prev; unit != nextunit; unit = unit->prev) {
  678.         if (is_unit(unit) && unit->id > 0
  679.         && alive(unit)
  680.         && inside_area(unit->x, unit->y)
  681.         && (unit->act && unit->act->initacp)) {
  682.         return unit;
  683.         }
  684.     }
  685.     }
  686.     return NULL;
  687. }
  688.  
  689. Unit *
  690. find_next_mover(side, prevunit)
  691. Side *side;
  692. Unit *prevunit;
  693. {
  694.     Unit *unit = NULL;
  695.  
  696.     if (side != NULL) {
  697.     if (prevunit == NULL)
  698.       prevunit = side->unithead;
  699.     for (unit = prevunit->next; unit != prevunit; unit = unit->next) {
  700.         if (is_unit(unit) && unit->id > 0
  701.         && alive(unit)
  702.         && inside_area(unit->x, unit->y)
  703.         && (unit->act && unit->act->acp > 0)) {
  704.         return unit;
  705.         }
  706.     }
  707.     }
  708.     return NULL;
  709. }
  710.  
  711. Unit *
  712. find_prev_mover(side, nextunit)
  713. Side *side;
  714. Unit *nextunit;
  715. {
  716.     Unit *unit = NULL;
  717.  
  718.     if (side != NULL) {
  719.     if (nextunit == NULL)
  720.       nextunit = side->unithead;
  721.     for (unit = nextunit->prev; unit != nextunit; unit = unit->prev) {
  722.         if (is_unit(unit) && unit->id > 0
  723.         && alive(unit)
  724.         && inside_area(unit->x, unit->y)
  725.         && (unit->act && unit->act->acp > 0)) {
  726.         return unit;
  727.         }
  728.     }
  729.     }
  730.     return NULL;
  731. }
  732.  
  733. Unit *
  734. find_next_awake_mover(side, prevunit)
  735. Side *side;
  736. Unit *prevunit;
  737. {
  738.     Unit *unit = NULL;
  739.  
  740.     if (side != NULL) {
  741.     if (prevunit == NULL)
  742.       prevunit = side->unithead;
  743.     for (unit = prevunit->next; unit != prevunit; unit = unit->next) {
  744.         if (is_unit(unit)
  745.         && unit->id > 0
  746.         && alive(unit)
  747.         && inside_area(unit->x, unit->y)
  748.         && (unit->act && unit->act->acp > 0)
  749.         && (unit->plan
  750.             && !unit->plan->asleep
  751.             && !unit->plan->reserve
  752.             && !unit->plan->delayed)) {
  753.         return unit;
  754.         }
  755.     }
  756.     }
  757.     return NULL;
  758. }
  759.  
  760. Unit *
  761. find_prev_awake_mover(side, nextunit)
  762. Side *side;
  763. Unit *nextunit;
  764. {
  765.     Unit *unit = NULL;
  766.  
  767.     if (side != NULL) {
  768.     if (nextunit == NULL) nextunit = side->unithead;
  769.     for (unit = nextunit->prev; unit != nextunit; unit = unit->prev) {
  770.         if (is_unit(unit) && unit->id > 0
  771.         && alive(unit)
  772.         && inside_area(unit->x, unit->y)
  773.                 && (unit->act && unit->act->acp > 0)
  774.                 && (unit->plan && !unit->plan->asleep && !unit->plan->reserve && !unit->plan->delayed)) {
  775.         return unit;
  776.         }
  777.     }
  778.     }
  779.     return NULL;
  780. }
  781.  
  782. /* Compute the total number of action points available to the side at the
  783.    beginning of the turn. */
  784.  
  785. int
  786. side_initacp(side)
  787. Side *side;
  788. {
  789.     int totacp = 0;
  790.     Unit *unit;
  791.  
  792.     for_all_side_units(side, unit) {
  793.     if (alive(unit) && unit->act) {
  794.         totacp += unit->act->initacp;
  795.     }
  796.     }
  797.     return totacp;
  798. }
  799.  
  800. /* Return the total of acp still unused by the side. */
  801.  
  802. int
  803. side_acp(side)
  804. Side *side;
  805. {
  806.     int acpleft = 0;
  807.     Unit *unit;
  808.  
  809.     for_all_side_units(side, unit) {
  810.     if (alive(unit) && unit->act) {
  811.         acpleft += unit->act->acp;
  812.     }
  813.     }
  814.     return acpleft;
  815. }
  816.  
  817. int
  818. side_acp_reserved(side)
  819. Side *side;
  820. {
  821.     int acpleft = 0;
  822.     Unit *unit;
  823.  
  824.     for_all_side_units(side, unit) {
  825.     if (alive(unit) && unit->act) {
  826.         if (unit->plan
  827.             && (unit->plan->reserve || unit->plan->asleep)) {
  828.             acpleft += unit->act->acp;
  829.         }
  830.     }
  831.     }
  832.     return acpleft;
  833. }
  834.  
  835. #if 0  /* not presently needed, but possibly useful */
  836. /* Return the total of acp still expected to be used by a human player. */
  837.  
  838. int
  839. side_acp_human(side)
  840. Side *side;
  841. {
  842.     int acpleft = 0;
  843.     Unit *unit;
  844.  
  845.     if (!side_has_display(side))
  846.       return acpleft;
  847.  
  848.     for_all_side_units(side, unit) {
  849.     if (unit != NULL
  850.         && alive(unit)
  851.         && inside_area(unit->x, unit->y)
  852.         && (unit->act
  853.         && unit->act->acp > 0)
  854.         && (unit->plan
  855.         && !unit->plan->asleep
  856.         && !unit->plan->reserve
  857.         && unit->plan->tasks == NULL)) {
  858.         acpleft += unit->act->acp;
  859.     }
  860.     }
  861.     return acpleft;
  862. }
  863. #endif
  864.  
  865. /* (note that technology could be "factored out" of a game if all sides
  866.    reach max tech at some point) */
  867. /* (otherwise should compute once and cache) */
  868. /* (note that once tech factors out, can never factor in again) */
  869.  
  870. int
  871. using_tech_levels()
  872. {
  873.     int u;
  874.     Side *side;
  875.  
  876.     for_all_sides(side) {
  877.     for_all_unit_types(u) {
  878.         if (side->tech[u] < u_tech_max(u)) return TRUE;
  879.     }
  880.     }
  881.     return FALSE;
  882. }
  883.  
  884. /* Take the given side out of the game entirely.  This does not imply
  885.    winning or losing, nor does it take down the side's display or AI. */
  886.  
  887. void
  888. remove_side_from_game(side)
  889. Side *side;
  890. {
  891.     Side *side2;
  892.  
  893.     /* Officially flag this side as being no longer in the game. */
  894.     side->ingame = FALSE;
  895.     /* Update everybody on this. */
  896.     for_all_sides(side2) {
  897.     update_side_display(side2, side, TRUE);
  898.     }
  899.     /* Note that we no longer try to remove any images from other sides'
  900.        views, because even with the side gone, the images may be useful
  901.        information about where its units had gotten to.  For instance,
  902.        if a unit had been captured shortly before the side lost, then its
  903.        image might still correspond to an actual unit, with only its side
  904.        changed, and other sides may want to investigate for themselves. */
  905. }
  906.  
  907. int
  908. num_displayed_sides()
  909. {
  910.     int n = 0;
  911.     Side *side;
  912.  
  913.     for_all_sides(side) {
  914.     if (side_has_display(side))
  915.       ++n;
  916.     }
  917.     return n;
  918. }
  919.  
  920. void
  921. set_side_name(side, side2, newname)
  922. Side *side, *side2;
  923. char *newname;
  924. {
  925.     side2->name = newname;
  926.     /* (should inform all other sides!) */
  927.     update_side_display(side, side2, TRUE);
  928. }
  929.  
  930. #ifdef DESIGNERS
  931.  
  932. void
  933. become_designer(side)
  934. Side *side;
  935. {
  936.     Side *side2;
  937.  
  938.     if (side->designer)
  939.       return;
  940.     side->designer = TRUE;
  941.     ++numdesigners;
  942.     /* Designers have godlike power in the game, so mark it (permanently)
  943.        as no longer a normal game. */
  944.     compromised = TRUE;
  945.     side->may_set_see_all = TRUE;
  946.     /* See everything by default - can turn off manually if desired. */
  947.     side->see_all = TRUE;
  948.     update_everything();
  949.     for_all_sides(side2) {
  950.     update_side_display(side2, side, TRUE);
  951.     }
  952. }
  953.  
  954. void
  955. become_nondesigner(side)
  956. Side *side;
  957. {
  958.     Side *side2;
  959.  
  960.     if (!side->designer)
  961.       return;
  962.     side->designer = FALSE;
  963.     --numdesigners;
  964.     side->may_set_see_all = FALSE;
  965.     side->see_all = all_see_all;
  966.     update_everything();
  967.     for_all_sides(side2) {
  968.     update_side_display(side2, side, TRUE);
  969.     }
  970. }
  971.  
  972. #endif /* DESIGNERS */
  973.  
  974. int
  975. trusted_side(side1, side2)
  976. Side *side1, *side2;
  977. {
  978.     if (side1 == side2)
  979.       return TRUE;
  980.     if (side1 == NULL || side2 == NULL || side1->trusts == NULL)
  981.       return FALSE;
  982.     return (side1->trusts[side_number(side2)]);
  983. }
  984.  
  985. void
  986. set_trust(side, side2, val)
  987. Side *side, *side2;
  988. int val;
  989. {
  990.     int oldval;
  991.     Side *side3;
  992.  
  993.     if (side == NULL || side2 == NULL || side == side2)
  994.       return;
  995.     if (side->trusts == NULL)
  996.       return;
  997.     oldval = side->trusts[side_number(side2)];
  998.     side->trusts[side_number(side2)] = val;
  999.     /* This is a major change that all other sides will know about. */
  1000.     if (oldval != val) {
  1001.     for_all_sides(side3) {
  1002.         if (active_display(side3)) {
  1003.         notify(side3, "%s %s %s",
  1004.                side_name(side),
  1005.                (val ? "now trusts" : "no longer trusts"),
  1006.                side_name(side2));
  1007.         update_side_display(side3, side, FALSE);
  1008.         update_side_display(side3, side2, TRUE);
  1009.         }
  1010.     }
  1011.     /* (should update views, list of units known about, etc) */
  1012.     /* (if cell goes from exact to only recorded, update display anyhow) */
  1013.     }
  1014. }
  1015.  
  1016. void
  1017. set_mutual_trust(side, side2, val)
  1018. Side *side, *side2;
  1019. int val;
  1020. {
  1021.     int oldval, oldval2;
  1022.     Side *side3;
  1023.  
  1024.     if (side == NULL || side2 == NULL || side == side2)
  1025.       return;
  1026.     if (side->trusts == NULL || side2->trusts == NULL)
  1027.       return;
  1028.     oldval = side->trusts[side_number(side2)];
  1029.     oldval2 = side2->trusts[side_number(side)];
  1030.     side->trusts[side_number(side2)] = val;
  1031.     side2->trusts[side_number(side)] = val;
  1032.     if (oldval != val || oldval2 != val) {
  1033.     for_all_sides(side3) {
  1034.         update_side_display(side3, side, FALSE);
  1035.         update_side_display(side3, side2, TRUE);
  1036.     }
  1037.     /* (should update views, list of units known about, etc) */
  1038.     }
  1039. }
  1040.  
  1041. /* What interfaces should use to tweak the autofinish flag. */
  1042.  
  1043. void
  1044. set_autofinish(side, value)
  1045. Side *side;
  1046. int value;
  1047. {
  1048.     side->autofinish = value;
  1049. }
  1050.  
  1051. /* Being at war requires only ones of the sides to consider itself so. */
  1052.  
  1053. /* (Should the other side's relationships be tweaked also?) */
  1054.  
  1055. int
  1056. enemy_side(s1, s2)
  1057. Side *s1, *s2;
  1058. {
  1059.     if (trusted_side(s1, s2))
  1060.       return FALSE;
  1061.     return TRUE;
  1062. }
  1063.  
  1064. /* A formal alliance requires the agreement of both sides. */
  1065.  
  1066. int
  1067. allied_side(s1, s2)
  1068. Side *s1, *s2;
  1069. {
  1070.     if (trusted_side(s1, s2))
  1071.       return TRUE;
  1072.     return FALSE;
  1073. }
  1074.  
  1075. /* Neutralness is basically anything else. */
  1076.  
  1077. int
  1078. neutral_side(s1, s2)
  1079. Side *s1, *s2;
  1080. {
  1081.     return (!enemy_side(s1, s2) && !allied_side(s1, s2));
  1082. }
  1083.  
  1084. void
  1085. set_willing_to_save(side, flag)
  1086. Side *side;
  1087. int flag;
  1088. {
  1089.     int oldflag = side->willingtosave;
  1090.     Side *side2;
  1091.  
  1092.     if (flag != oldflag) {
  1093.     side->willingtosave = flag;
  1094.     /* Inform everybody of our willingness to save. */
  1095.     for_all_sides(side2) {
  1096.         if (active_display(side2)) {
  1097.         notify(side2, "%s is%s willing to save the game.",
  1098.                   side_name(side), (flag ? "" : " not"));
  1099.         update_side_display(side2, side, TRUE);
  1100.         }
  1101.     }
  1102.     }
  1103. }
  1104.  
  1105. void
  1106. set_willing_to_draw(side, flag)
  1107. Side *side;
  1108. int flag;
  1109. {
  1110.     int oldflag = side->willingtodraw;
  1111.     Side *side2;
  1112.  
  1113.     if (flag != oldflag) {
  1114.     side->willingtodraw = flag;
  1115.     /* Inform everybody of our willingness to draw. */
  1116.     for_all_sides(side2) {
  1117.         if (active_display(side2)) {
  1118.         notify(side2, "%s is%s willing to declare the game a draw.",
  1119.                   side_name(side), (flag ? "" : " not"));
  1120.         update_side_display(side2, side, TRUE);
  1121.         }
  1122.     }
  1123.     }
  1124. }
  1125.  
  1126. /* Set the self-unit of the given side.  This is only called when done at
  1127.    the direction of the side, and may fail if the side can't change its
  1128.    self-unit voluntarily.  Return success or failure of change. */
  1129.  
  1130. int
  1131. set_side_self_unit(side, unit)
  1132. Side *side;
  1133. Unit *unit;
  1134. {
  1135.     if (!in_play(unit))
  1136.       return FALSE;
  1137.     if (side->self_unit
  1138.         && in_play(side->self_unit)
  1139.         && !u_self_changeable(side->self_unit->type))
  1140.       return FALSE;
  1141.     side->self_unit = unit;
  1142.     /* (should update some part of display?) */
  1143.     return TRUE;
  1144. }
  1145.  
  1146. /* Message-forwarding function. */
  1147.  
  1148. void
  1149. send_message(side, sidemask, str)
  1150. Side *side;
  1151. SideMask sidemask;
  1152. char *str;
  1153. {
  1154.     Side *side2;
  1155.  
  1156.     for_all_sides(side2) {
  1157.     if (side2 != side && (sidemask & (1 << side2->id))) {
  1158.         receive_message(side2, side, str);
  1159.     }
  1160.     }
  1161. }
  1162.  
  1163. /* Handle the receipt of a message.  Some messages may result in specific
  1164.    actions, but the default is just to forward to AIs and displays. */
  1165.  
  1166. void
  1167. receive_message(side, sender, str)
  1168. Side *side, *sender;
  1169. char *str;
  1170. {
  1171.     /* First look for specially-recognized messages. */
  1172.     if (strcmp("%reveal", str) == 0) {
  1173.     reveal_side(sender, side, NULL);
  1174.     } else {
  1175.     /* Give the message to interface if present. */
  1176.     if (side_has_display(side)) {
  1177.         update_message_display(side, sender, str, TRUE);
  1178.     }
  1179.     /* Also give the message to any AI. */
  1180.     if (side_has_ai(side)) {
  1181.         ai_receive_message(side, sender, str);
  1182.     }
  1183.     }
  1184. }
  1185.  
  1186. /* General method for passing along info about one side to another. */
  1187.  
  1188. void
  1189. reveal_side(sender, recipient, types)
  1190. Side *sender, *recipient;
  1191. int *types;
  1192. {
  1193.     int x, y;
  1194.     Unit *unit;
  1195.  
  1196.     if (all_see_all)
  1197.       return;
  1198.     if (!g_terrain_seen()) {
  1199.     for_all_cells(x, y) {
  1200.         if (terrain_view(sender, x, y) != UNSEEN
  1201.             && terrain_view(recipient, x, y) == UNSEEN) {
  1202.             set_terrain_view(recipient, x, y, terrain_view(sender, x, y));
  1203.             /* (should update unit views also) */
  1204.         update_cell_display(recipient, x, y, TRUE);
  1205.         }
  1206.     }
  1207.     }
  1208.     for_all_side_units(sender, unit) {
  1209.     if (in_play(unit) && (types == NULL || types[unit->type])) {
  1210.         see_exact(recipient, unit->x, unit->y);
  1211.         update_cell_display(recipient, unit->x, unit->y, TRUE);
  1212.     }
  1213.     }
  1214. }
  1215.  
  1216. /* Vision. */
  1217.  
  1218. void
  1219. calc_vision(side)
  1220. Side *side;
  1221. {
  1222. }
  1223.  
  1224. /* What happens when a unit appears on a given cell. */
  1225.  
  1226. /* An always-seen unit has builtin spies/tracers to inform everybody else of
  1227.    all its movements.  When such a unit occupies a cell, coverage is turned
  1228.    on and remains on until the unit leaves that cell. */
  1229.  
  1230. /* If this unit with onboard spies wanders into unknown territory,
  1231.    shouldn't that territory become known as well?  I think the unseen
  1232.    test should only apply during initialization. */
  1233. /* But if always-seen unit concealed during init, will magically appear
  1234.    when it first moves! */
  1235.  
  1236. void
  1237. all_see_occupy(unit, x, y, inopen)
  1238. Unit *unit;
  1239. int x, y;
  1240. int inopen;
  1241. {
  1242.     Side *side;
  1243.     int always = u_see_always(unit->type);
  1244.     
  1245.     for_all_sides(side) {
  1246.     if (side->see_all) {
  1247.         update_cell_display(side, x, y, TRUE);
  1248.     } if (side_sees_unit(side, unit)) {
  1249.         see_cell(side, x, y);
  1250.     } else {
  1251.         if (always && terrain_view(side, x, y) != UNSEEN) {
  1252.         add_cover(side, x, y, 1);
  1253.         set_alt_cover(side, x, y, 0);
  1254.         }
  1255.         if (inopen || always) {
  1256.         see_cell(side, x, y);
  1257.         }
  1258.     }
  1259.     }
  1260.     {
  1261.     int dir, x1, y1;
  1262.     Unit *unit2, *unit3;
  1263.             
  1264.     for_all_directions(dir) {
  1265.         if (interior_point_in_dir(x, y, dir, &x1, &y1)) {
  1266.            for_all_stack(x1, y1, unit2) {
  1267.                if (unit2->side != NULL
  1268.                    && unit2->side != unit->side
  1269.                    && units_visible(unit2->side, x, y)
  1270.                    && !unit_trusts_unit(unit2, unit)) {
  1271.                    wake_unit(unit2, FALSE, 0, NULL);
  1272.                }
  1273.                for_all_occupants(unit2, unit3) {
  1274.             if (unit3->side != NULL
  1275.                 && unit3->side != unit->side
  1276.                 && units_visible(unit3->side, x, y)
  1277.                 && !unit_trusts_unit(unit3, unit)) {
  1278.                 wake_unit(unit3, FALSE, 0, NULL);
  1279.             }
  1280.                }
  1281.            }
  1282.         }
  1283.     }
  1284.     }
  1285. }
  1286.  
  1287. /* Some highly visible unit types cannot leave a cell without everybody
  1288.    knowing about the event.  The visibility is attached to the unit, not
  1289.    the cell, so first the newly-empty cell is viewed, then view coverage
  1290.    is decremented. */
  1291.  
  1292. void
  1293. all_see_leave(unit, x, y, inopen)
  1294. Unit *unit;
  1295. int x, y;
  1296. int inopen;
  1297. {
  1298.     Side *side;
  1299.     int always = u_see_always(unit->type);
  1300.     int olduview;
  1301.  
  1302.     for_all_sides(side) {
  1303.     if (side->see_all) {
  1304.         update_cell_display(side, x, y, TRUE);
  1305.     } else if (side_sees_unit(side, unit)) {
  1306.         see_cell(side, x, y);
  1307.     } else {
  1308.         if (always && terrain_view(side, x, y) != UNSEEN) {
  1309.         see_cell(side, x, y);
  1310.         if (cover(side, x, y) > 0)
  1311.           add_cover(side, x, y, -1);
  1312.         if (side->alt_coverage)
  1313.           /* (should recalc alt coverage, since was 0) */;
  1314.         }
  1315.         /* Won't be called twice, because view coverage is 0 now. */
  1316.         if (inopen) {
  1317.         see_cell(side, x, y);
  1318.         }
  1319.         /* special hack to flush images we *know* are garbage */
  1320.         if (cover(side, x, y) < 1) {
  1321.             olduview = unit_view(side, x, y);
  1322.             if (vside(olduview) == side_number(side)) {
  1323.                 set_unit_view(side, x, y, EMPTY);
  1324.                 set_unit_view_date(side, x, y, g_turn());
  1325.             update_cell_display(side, x, y, FALSE);
  1326.             }
  1327.         }
  1328.     }
  1329.     }
  1330. }
  1331.  
  1332. static int tmpx0, tmpy0, tmpz0;
  1333. static int tmpnx, tmpny, tmpnz;
  1334.  
  1335. static void
  1336. init_visible_elevation(x, y)
  1337. int x, y;
  1338. {
  1339.     int elev = checked_elev_at(x, y);
  1340.  
  1341.     set_tmp2_at(x, y, elev - tmpz0);
  1342. }
  1343.  
  1344. static void
  1345. init_visible_elevation_2(x, y)
  1346. int x, y;
  1347. {
  1348.     int elev = checked_elev_at(x, y);
  1349.  
  1350.     set_tmp3_at(x, y, elev - tmpnz);
  1351. }
  1352.  
  1353. /* (should reindent) */
  1354. static void
  1355. calc_visible_elevation(x, y)
  1356. int x, y;
  1357. {
  1358.     int dir, x1, y1, elev, tmp, tmpa, tmpb, adjelev = 9999, viselev, dist, dist1;
  1359.     int cellwid = area.cellwidth;
  1360.  
  1361.     elev = checked_elev_at(x, y);
  1362.     dist = distance(x, y, tmpx0, tmpy0);
  1363.     if (cellwid <= 0)
  1364.       cellwid = 1;
  1365.     for_all_directions(dir) {
  1366.     if (point_in_dir(x, y, dir, &x1, &y1)) {
  1367.       dist1 = distance(x1, y1, tmpx0, tmpy0);
  1368.       if (dist1 < dist) {
  1369.         tmpa = tmp2_at(x1, y1);
  1370.         /* Account for the screening effect of the elevation difference. */
  1371.         /* (dist1 will never be zero) */
  1372.         tmpa = (tmpa * dist * cellwid) / (dist1 * cellwid);
  1373.         tmpb = checked_elev_at(x1, y1)
  1374.                + t_thickness(terrain_at(x1, y1))
  1375.                - tmpz0;
  1376.         tmpb = (tmpb * dist * cellwid) / (dist1 * cellwid);
  1377.         tmp = max(tmpa, tmpb);
  1378.         adjelev = min(adjelev, tmp + tmpz0);
  1379.       }
  1380.     }
  1381.     }
  1382.     viselev = max(adjelev, elev);
  1383.     set_tmp2_at(x, y, viselev - tmpz0);
  1384. }
  1385.  
  1386. /* (should reindent) */
  1387. static void
  1388. calc_visible_elevation_2(x, y)
  1389. int x, y;
  1390. {
  1391.     int dir, x1, y1, elev, tmp, tmpa, tmpb, adjelev = 9999, viselev, dist, dist1;
  1392.     int cellwid = area.cellwidth;
  1393.  
  1394.     elev = checked_elev_at(x, y);
  1395.     dist = distance(x, y, tmpnx, tmpny);
  1396.     if (cellwid <= 0)
  1397.       cellwid = 1;
  1398.     for_all_directions(dir) {
  1399.     if (point_in_dir(x, y, dir, &x1, &y1)) {
  1400.       dist1 = distance(x1, y1, tmpnx, tmpny);
  1401.       if (dist1 < dist) {
  1402.         tmpa = tmp3_at(x1, y1);
  1403.         /* Account for the screening effect of the elevation difference. */
  1404.         /* (dist1 will never be zero) */
  1405.         tmpa = (tmpa * dist * cellwid) / (dist1 * cellwid);
  1406.         tmpb = checked_elev_at(x1, y1)
  1407.                + t_thickness(terrain_at(x1, y1))
  1408.                - tmpnz;
  1409.         tmpb = (tmpb * dist * cellwid) / (dist1 * cellwid);
  1410.         tmp = max(tmpa, tmpb);
  1411.         adjelev = min(adjelev, tmp + tmpnz);
  1412.       }
  1413.     }
  1414.     }
  1415.     viselev = max(adjelev, elev);
  1416.     set_tmp3_at(x, y, viselev - tmpnz);
  1417. }
  1418.  
  1419. /* Unit's beady eyes are shifting from one location to another.
  1420.    Since new things may be coming into view, we have to check and maybe
  1421.    draw lots of cells (but only need the one output flush, fortunately). */
  1422.  
  1423. /* (LOS comes in here, to make irregular coverage areas) */
  1424.  
  1425. void
  1426. cover_area(side, unit, x0, y0, nx, ny)
  1427. Side *side;
  1428. Unit *unit;
  1429. int x0, y0, nx, ny;
  1430. {
  1431.     int u = unit->type, range0, nrange, range, x, y, x1, y1, x2, y2, y1c, y2c, xw, cov, los, r;
  1432.     int xmin, ymin, xmax, ymax, oldcov, newcov, anychanges;
  1433.     extern int daynight, sunx, suny;
  1434.  
  1435.     if (side == NULL
  1436.     || side->coverage == NULL
  1437.         || indep(unit)
  1438.     || all_see_all
  1439.     || !completed(unit)
  1440.     )
  1441.       return;
  1442.     range0 = nrange = u_vision_range(u);
  1443.     /* Adjust for the effects of nighttime on vision range. */
  1444.     if (in_area(x0, y0)) {
  1445.     if (night_at(x0, y0)) {
  1446.         range0 =
  1447.           (range0 * ut_vision_night_effect(u, terrain_at(x0, y0))) / 100;
  1448.     }
  1449.     } else {
  1450.     range0 = 0;
  1451.     }
  1452.     if (in_area(nx, ny)) {
  1453.     if (night_at(nx, ny)) {
  1454.         nrange =
  1455.           (nrange * ut_vision_night_effect(u, terrain_at(nx, ny))) / 100;
  1456.     }
  1457.     } else {
  1458.     nrange = 0;
  1459.     }
  1460.     range = max(range0, nrange);
  1461.     allocate_area_scratch(1);
  1462.     anychanges = FALSE;
  1463.     /* First, set the union of the from and to areas to the existing
  1464.        coverage. */
  1465.     /* These may be outside the area - necessary since units may be able
  1466.        to see farther in x than the height of the area. */
  1467.     /* Compute the maximum bounds that may be affected. */
  1468.     if (y0 >= 0) {
  1469.     if (ny >= 0) {
  1470.         ymin = min(y0, ny);
  1471.         ymax = max(y0, ny);
  1472.     } else {
  1473.         ymin = ymax = y0;
  1474.     }
  1475.     } else if (ny >= 0) {
  1476.     ymin = ymax = ny;
  1477.     }
  1478.     if (x0 >= 0) {
  1479.     if (nx >= 0) {
  1480.         xmin = min(x0, nx);
  1481.         xmax = max(x0, nx);
  1482.     } else {
  1483.         xmin = xmax = x0;
  1484.     }
  1485.     } else if (nx >= 0) {
  1486.     xmin = xmax = nx;
  1487.     }
  1488.     if (any_los) {
  1489.     /* Need extra scratch layers, will be used for visible
  1490.            elevation cache. */
  1491.     allocate_area_scratch(3);
  1492.     }
  1493.     los = FALSE;
  1494.     /* (should also adjust for effect of clouds here) */
  1495.     if (u_vision_bend(u) != 100) {
  1496.     los = TRUE;
  1497.     /* Compute the minimum elevation for visibility at each cell. */
  1498.     if (in_area(x0, y0)) {
  1499.         tmpx0 = x0;  tmpy0 = y0;
  1500.         tmpz0 = checked_elev_at(x0, y0)
  1501.         + unit_alt(unit)
  1502.         + ut_eye_height(u, terrain_at(x0, y0));
  1503.         apply_to_area(x0, y0, range0, init_visible_elevation);
  1504.         /* Leave own and adj cells alone, they will always be visible. */
  1505.         for (r = 2; r <= range0; ++r) {
  1506.         apply_to_ring(x0, y0, r, r, calc_visible_elevation);
  1507.         }
  1508.         /* We now have a layer indicating how high things must be
  1509.                to be visible. */
  1510.     }
  1511.     if (in_area(nx, ny)) {
  1512.         tmpnx = nx;  tmpny = ny;
  1513.         tmpnz = checked_elev_at(nx, ny)
  1514.         + unit_alt(unit)
  1515.         + ut_eye_height(u, terrain_at(nx, ny));
  1516.         apply_to_area(nx, ny, nrange, init_visible_elevation_2);
  1517.         /* Leave own and adj cells alone, they will always be visible. */
  1518.         for (r = 2; r <= nrange; ++r) {
  1519.         apply_to_ring(nx, ny, r, r, calc_visible_elevation_2);
  1520.         }
  1521.         /* We now have another layer, indicating how high things must be
  1522.                to be visible from the new location. */
  1523.     }
  1524.     }
  1525.     /* Copy the current coverage into the tmp layer. */
  1526.     y1 = y1c = ymin - range;
  1527.     y2 = y2c = ymax + range;
  1528.     /* Clip the iteration bounds. */
  1529.     if (y1c < 0)
  1530.       y1c = 0;
  1531.     if (y2c > area.height - 1)
  1532.       y2c = area.height - 1;
  1533.     for (y = y1c; y <= y2c; ++y) {
  1534.     x1 = xmin - range;
  1535.     x2 = xmax + range;
  1536.     for (x = x1; x <= x2; ++x) {
  1537.         if (in_area(x, y)) {
  1538.         xw = wrapx(x);
  1539.         set_tmp1_at(xw, y, cover(side, xw, y));
  1540.         }
  1541.     }
  1542.     }
  1543.     /* Decrement coverage around the old location. */
  1544.     if (in_area(x0, y0)) {
  1545.     y1 = y1c = y0 - range0;
  1546.     y2 = y2c = y0 + range0;
  1547.     /* Clip the iteration bounds. */
  1548.     if (y1c < 0)
  1549.       y1c = 0;
  1550.     if (y2c > area.height - 1)
  1551.       y2c = area.height - 1;
  1552.     for (y = y1c; y <= y2c; ++y) {
  1553.         x1 = x0 - (y < y0 ? (y - y1) : range0);
  1554.         x2 = x0 + (y > y0 ? (y2 - y) : range0);
  1555.         for (x = x1; x <= x2; ++x) {
  1556.         if (in_area(x, y)) {
  1557.             xw = wrapx(x);
  1558.             if (!los
  1559.             || ((tmp2_at(xw, y) + tmpz0)
  1560.                 <= (checked_elev_at(xw, y)
  1561.                 + t_thickness(terrain_at(xw, y))))) {
  1562.             cov = tmp1_at(xw, y) - 1;
  1563.             /* Should never go negative, detect if so. */
  1564.             if (cov < 0) {
  1565.                 Dprintf("Negative coverage for %s at %d,%d\n",
  1566.                     side_desig(side), xw, y);
  1567.             }
  1568.             set_tmp1_at(xw, y, cov);
  1569.             }
  1570.             if (los && (alt_cover(side, xw, y) == (tmp2_at(xw, y) + tmpz0)))
  1571.               /* this unit set the min, should recalc alt coverage now */;
  1572.         }
  1573.         }
  1574.     }
  1575.     }
  1576.     /* Increment coverage around the new location. */
  1577.     if (in_area(nx, ny)) {
  1578.     y1 = y1c = ny - nrange;
  1579.     y2 = y2c = ny + nrange;
  1580.     /* Clip the iteration bounds. */
  1581.     if (y1c < 0)
  1582.       y1c = 0;
  1583.     if (y2c > area.height - 1)
  1584.       y2c = area.height - 1;
  1585.     for (y = y1c; y <= y2c; ++y) {
  1586.         x1 = nx - (y < ny ? (y - y1) : nrange);
  1587.         x2 = nx + (y > ny ? (y2 - y) : nrange);
  1588.         for (x = x1; x <= x2; ++x) {
  1589.         if (in_area(x, y)) {
  1590.             xw = wrapx(x);
  1591.             if (!los
  1592.             || ((tmp3_at(xw, y) + tmpnz)
  1593.                 <= (checked_elev_at(xw, y)
  1594.                 + t_thickness(terrain_at(xw, y))))) {
  1595.             cov = tmp1_at(xw, y) + 1;
  1596.             set_tmp1_at(xw, y, cov);
  1597.             }
  1598.             if (los)
  1599.               set_alt_cover(side, xw, y, min(alt_cover(side, xw, y), (tmp3_at(xw, y) + tmpnz)));
  1600.         }
  1601.         }
  1602.     }
  1603.     }
  1604.     /* Now update the actual coverage.  Do this over an area that includes
  1605.        both the decrement and increment changes. */
  1606.     y1 = y1c = ymin - range;
  1607.     y2 = y2c = ymax + range;
  1608.     /* Clip the iteration bounds. */
  1609.     if (y1c < 0)
  1610.       y1c = 0;
  1611.     if (y2c > area.height - 1)
  1612.       y2c = area.height - 1;
  1613.     for (y = y1c; y <= y2c; ++y) {
  1614.     x1 = xmin - range;
  1615.     x2 = xmax + range;
  1616.     for (x = x1; x <= x2; ++x) {
  1617.         if (in_area(x, y)) {
  1618.         xw = wrapx(x);
  1619.         oldcov = cover(side, xw, y);
  1620.         newcov = tmp1_at(xw, y);
  1621.         if (newcov != oldcov) {
  1622.             set_cover(side, xw, y, newcov);
  1623.             if (newcov > oldcov && see_cell(side, xw, y))
  1624.               react_to_seen_unit(side, unit, xw, y);
  1625.             if ((newcov > 0 && oldcov == 0)
  1626.             || (newcov == 0 && oldcov > 0))
  1627.               update_cell_display(side, xw, y, 36);
  1628.             anychanges = TRUE;
  1629.         }
  1630.         }
  1631.     }
  1632.     }
  1633.     /* If we're seeing new things, make sure they're on the display. */
  1634.     if (anychanges)
  1635.       flush_display_buffers(side);
  1636. }
  1637.  
  1638. /* Use this to clear out garbled view coverage. */
  1639.  
  1640. void
  1641. reset_coverage()
  1642. {
  1643.     Side *side;
  1644.  
  1645.     if (all_see_all)
  1646.       return;
  1647.     for_all_sides(side)
  1648.       calc_coverage(side);
  1649. }
  1650.  
  1651. /* Calculate/recalculate the view coverage layers of a side. */
  1652.  
  1653. void
  1654. calc_coverage(side)
  1655. Side *side;
  1656. {
  1657.     int x, y, s2, pop, visible[MAXSIDES];
  1658.     Unit *unit;
  1659.  
  1660.     if (side->coverage == NULL)
  1661.       return;
  1662.     Dprintf("Calculating all view coverage for %s\n", side_desig(side));
  1663.     /* Either init all cells to 0, or use populations to decide. */
  1664.     if (people_sides_defined()) {
  1665.     for (s2 = 0; s2 <= numsides; ++s2)
  1666.       visible[s2] = (trusted_side(side_n(s2), side) ? 1 : 0);
  1667.     /* (should add controlled sides too) */
  1668.     for_all_cells(x, y) {
  1669.         pop = people_side_at(x, y);
  1670.         set_cover(side, x, y, ((pop != NOBODY && visible[pop]) ? 1 : 0));
  1671.     }
  1672.     } else {
  1673.     for_all_cells(x, y) {
  1674.         set_cover(side, x, y, 0);
  1675.     }
  1676.     }
  1677.     /* Add coverage by, and of, the units already in place. */
  1678.     for_all_units(unit) {
  1679.     if (in_play(unit)) {
  1680.         if (unit->side != NULL && trusted_side(unit->side, side)) {
  1681.         cover_area(side, unit, -1, -1, unit->x, unit->y);
  1682.         } else if (u_see_always(unit->type)
  1683.                && terrain_view(side, unit->x, unit->y) != UNSEEN) {
  1684.         add_cover(side, unit->x, unit->y, 1);
  1685.         }
  1686.     }
  1687.     }
  1688. }
  1689.  
  1690. void
  1691. reset_all_views()
  1692. {
  1693.     Side *side;
  1694.  
  1695.     if (all_see_all)
  1696.       return;
  1697.     for_all_sides(side) {
  1698.     reset_view(side);
  1699.     }
  1700. }
  1701.  
  1702. void
  1703. reset_view(side)
  1704. Side *side;
  1705. {
  1706.     int x, y, uview;
  1707.  
  1708.     for_all_cells(x, y) {
  1709.     if (cover(side, x, y) == 0
  1710.         && ((uview = unit_view(side, x, y)) != EMPTY)
  1711.         && vside(uview) == side_number(side)) {
  1712.         set_unit_view(side, x, y, EMPTY);
  1713.     }
  1714.     }
  1715. }
  1716.  
  1717. void
  1718. react_to_seen_unit(side, unit, x, y)
  1719. Side *side;
  1720. Unit *unit;
  1721. int x, y;
  1722. {
  1723.     int uview, eu;
  1724.     Unit *eunit;
  1725.     Side *es;
  1726.  
  1727.     if (all_see_all /* see real unit */) {
  1728.         /* (should look at all of stack if can be mixed) */
  1729.     if ((eunit = unit_at(x, y)) != NULL) {
  1730.         if (react_to_enemies(unit) && !allied_side(eunit->side, side)) {
  1731.         /* should do a more general alarm */
  1732.             wake_unit(unit, TRUE, 0, NULL);
  1733.         }
  1734.     }
  1735.     } else if (side->coverage != NULL) {
  1736.     uview = unit_view(side, x, y);
  1737.         if (uview != EMPTY) {
  1738.             eu = vtype(uview);  es = side_n(vside(uview));
  1739.             /* react only to certain utypes? */
  1740.         if (react_to_enemies(unit) && !allied_side(es, side)) {
  1741.         /* should do a more general alarm */
  1742.         wake_unit(unit, TRUE, 0, NULL);
  1743.         }
  1744.         }
  1745.     } else {
  1746.         /* ??? */
  1747.     }
  1748. }
  1749.  
  1750. extern void compute_see_chances PARAMS ((void));
  1751.  
  1752. int any_see_chances = -1;
  1753.  
  1754. int any_people_see_chances = -1;
  1755.  
  1756. int max_see_chance_range;
  1757.  
  1758. /* Determine whether there is any possibility of an uncertain sighting,
  1759.    and cache the conclusion. */
  1760.  
  1761. void
  1762. compute_see_chances()
  1763. {
  1764.     int u1, u2, m1;
  1765.  
  1766.     any_see_chances = FALSE;
  1767.     any_people_see_chances = FALSE;
  1768.     max_see_chance_range = -1;
  1769.     for_all_unit_types(u2) {
  1770.     for_all_unit_types(u1) {
  1771.         if (uu_see_at(u1, u2) != 100) {
  1772.         any_see_chances = TRUE;
  1773.         max_see_chance_range = max(max_see_chance_range, 0);
  1774.         }
  1775.         if (uu_see_adj(u1, u2) != 100) {
  1776.         any_see_chances = TRUE;
  1777.         max_see_chance_range = max(max_see_chance_range, 1);
  1778.         }
  1779.         if (uu_see(u1, u2) != 100) {
  1780.         any_see_chances = TRUE;
  1781.         max_see_chance_range = max(max_see_chance_range, u_vision_range(u1));
  1782.         }
  1783.     }
  1784.     for_all_material_types(m1) {
  1785.         if (um_people_see(u2, m1)) {
  1786.         any_people_see_chances = TRUE;
  1787.         }
  1788.     }
  1789.     }
  1790. }
  1791.  
  1792. int test_for_viewer PARAMS ((int x, int y));
  1793.  
  1794. static Unit *tmpunittosee, *tmpunitseen;
  1795.  
  1796. int
  1797. test_for_viewer(x, y)
  1798. int x, y;
  1799. {
  1800.     int u2 = tmpunittosee->type, x2 = tmpunittosee->x, y2 = tmpunittosee->y, dist, chance;
  1801.     Unit *unit;
  1802.  
  1803.     dist = distance(x, y, x2, y2);
  1804.     for_all_stack(x, y, unit) {
  1805.     if (dist == 1)
  1806.       chance = uu_see_adj(unit->type, u2);
  1807.     else
  1808.       /* (should interpolate according to distance?) */
  1809.       chance = uu_see(unit->type, u2);
  1810.     chance = (chance * ut_visibility(u2, terrain_at(x2, y2))) / 100;
  1811.     if (chance >= 100 || probability(chance)) {
  1812.         tmpunitseen = tmpunittosee;
  1813.         return TRUE;
  1814.     }
  1815.     }
  1816.     return FALSE;
  1817. }
  1818.  
  1819. /* Update the view of this cell for everybody's benefit.  May have to write
  1820.    to many displays. */
  1821.  
  1822. void
  1823. all_see_cell(x, y)
  1824. int x, y;
  1825. {
  1826.     register Side *side;
  1827.  
  1828.     for_all_sides(side) {
  1829.     see_cell(side, x, y);
  1830.     }
  1831. }
  1832.  
  1833. /* Look at the given position, possibly not seeing anything.  Return true if
  1834.    a unit was spotted. */
  1835.  
  1836. static int see_weather PARAMS ((Side *side, int x, int y));
  1837.  
  1838. int
  1839. see_cell(side, x, y)
  1840. Side *side;
  1841. int x, y;
  1842. {
  1843.     int update, chance, t, curview, curuview, newuview, x1, y1, m, wupdate;
  1844.     Unit *unit, *unitseen;
  1845.  
  1846.     if (side == NULL || side == indepside || !in_area(x, y))
  1847.       return FALSE;
  1848.     update = FALSE;
  1849.     unitseen = NULL;
  1850.     /* If we see everything, just pass through to updating the display. */
  1851.     if (side->see_all) {
  1852.         update = TRUE;
  1853.         unitseen = unit_at(x, y);
  1854.     } else if (cover(side, x, y) > 0) {
  1855.         /* Always update our knowledge of the terrain. */
  1856.         curview = terrain_view(side, x, y);
  1857.      if (curview == UNSEEN || !g_see_terrain_always()) {
  1858.         set_terrain_view(side, x, y, buildtview(terrain_at(x, y)));
  1859.         if (!g_see_terrain_always())
  1860.           set_terrain_view_date(side, x, y, g_turn());
  1861.         update = TRUE;
  1862.     }
  1863.     if (temperatures_defined() || clouds_defined() || winds_defined()) {
  1864.         wupdate = see_weather(side, x, y);
  1865.         if (wupdate)
  1866.           update = TRUE;
  1867.     }
  1868.     if (any_see_chances < 0)
  1869.       compute_see_chances();
  1870.        curuview = unit_view(side, x, y);
  1871.        for_all_stack(x, y, unit) {
  1872.         if (side_sees_unit(side, unit)) {
  1873.         unitseen = unit;
  1874.         break;
  1875.         } else if (any_see_chances) {
  1876.             /* (should always check for viewers at x,y first) */
  1877.         if (max_see_chance_range > 0) {
  1878.             tmpunittosee = unit;
  1879.             if (search_around(x, y, max_see_chance_range, test_for_viewer,
  1880.                           &x1, &y1, 1)) {
  1881.                 unitseen = tmpunitseen;
  1882.                 break;
  1883.             }
  1884.         }
  1885.         } else {
  1886.         t = terrain_at(x, y);
  1887.         chance = ut_visibility(unit->type, t);
  1888.         if (chance >= 100 || probability(chance)) {
  1889.             unitseen = unit;
  1890.             break;
  1891.         }
  1892.         }
  1893.     }
  1894.     /* If there is still a unit to be seen at this location, then we know
  1895.        that there was a stack before, so update to draw just the units left. */
  1896.     if (unitseen)
  1897.       update = TRUE;
  1898.     /* See if any people in the cell see something. */
  1899.     if (any_people_see_chances
  1900.         && unitseen == NULL
  1901.         && any_cell_materials_defined()) {
  1902.            for_all_stack(x, y, unit) {
  1903.         for_all_material_types(m) {
  1904.             if (cell_material_defined(m)
  1905.             && material_at(x, y, m) > 0) {
  1906.             chance = um_people_see(unit->type, m);
  1907.             if (probability(chance)) {
  1908.                 unitseen = unit;
  1909.                 break;
  1910.             }
  1911.             }
  1912.         }
  1913.         if (unitseen != NULL)
  1914.           break;
  1915.            }
  1916.     }
  1917.     if (unitseen) {
  1918.         newuview = builduview(side_number(unitseen->side), unitseen->type);
  1919.         if (curuview != newuview) {
  1920.         /* We're seeing something different from what used to be there. */
  1921.         set_unit_view(side, x, y, newuview);
  1922.             set_unit_view_date(side, x, y, g_turn());
  1923.         update = TRUE;
  1924.         } else {
  1925.             /* Same as we already know, so not considered a change. */
  1926.             unitseen = NULL;
  1927.         }
  1928.     } else if (curuview != EMPTY) {
  1929.         set_unit_view(side, x, y, EMPTY);
  1930.         set_unit_view_date(side, x, y, g_turn());
  1931.         update = TRUE;
  1932.     }
  1933.     }
  1934.     /* If there was any change in what was visible, tell the display. */
  1935.     if (update) {
  1936.     update_cell_display(side, x, y, FALSE);
  1937.     }
  1938.     return (unitseen != NULL);
  1939. }
  1940.  
  1941. /* "Bare-bones" viewing, for whenever you know exactly what's there.
  1942.    This is the lowest level of all viewing routines, and executed a lot. */
  1943.  
  1944. void
  1945. see_exact(side, x, y)
  1946. Side *side;
  1947. int x, y;
  1948. {
  1949.     register int olduview, oldtview, newtview, newuview, update, wupdate;
  1950.     register Unit *unit;
  1951.  
  1952.     if (side == NULL || side == indepside || !in_area(x, y))
  1953.       return;
  1954.     if (all_see_all) {
  1955.     /* It may not really be necessary to do anything to the display, but
  1956.        the kernel doesn't know if the interface is drawing all the units
  1957.        that are visible, or is only drawing "interesting" ones, or whatever.
  1958.        It would be up to the interface to decide that, say, its magnification
  1959.        power for a map is such that only one unit is being displayed, and
  1960.        that the update from here doesn't result in any visible changes to
  1961.        what's already been drawn on the screen. */
  1962.         update = TRUE;
  1963.     } else {
  1964.     update = FALSE;
  1965.         oldtview = terrain_view(side, x, y);
  1966.         newtview = buildtview(terrain_at(x, y));
  1967.         set_terrain_view(side, x, y, newtview);
  1968.     set_terrain_view_date(side, x, y, g_turn());
  1969.     if (oldtview != newtview)
  1970.       update = TRUE;
  1971.     wupdate = see_weather(side, x, y);
  1972.     if (wupdate)
  1973.       update = TRUE;
  1974.         olduview = unit_view(side, x, y);
  1975.         newuview = EMPTY;
  1976.         unit = unit_at(x, y);
  1977.     if (unit != NULL)
  1978.       newuview = builduview(side_number(unit->side), unit->type);
  1979.     set_unit_view(side, x, y, newuview);
  1980.     set_unit_view_date(side, x, y, g_turn());
  1981.     if (olduview != newuview)
  1982.       update = TRUE;
  1983.     }
  1984.     /* If there was any change in what was visible, tell the display. */
  1985.     if (update) {
  1986.     update_cell_display(side, x, y, FALSE);
  1987.     }
  1988. }
  1989.  
  1990. static int
  1991. see_weather(side, x, y)
  1992. Side *side;
  1993. int x, y;
  1994. {
  1995.     int curview, update;
  1996.  
  1997.     update = FALSE;
  1998.     if (temperatures_defined()) {
  1999.     see_weather(side, x, y);
  2000.     curview = temperature_view(side, x, y);
  2001.     if (curview != temperature_at(x, y)) {
  2002.         set_temperature_view(side, x, y, temperature_at(x, y));
  2003.         update = TRUE;
  2004.     }
  2005.     /* Even if the data didn't change, our information is
  2006.        now up-to-date. */
  2007.     if (!g_see_weather_always())
  2008.       set_temperature_view_date(side, x, y, g_turn());
  2009.     }
  2010.     if (clouds_defined()) {
  2011.     curview = cloud_view(side, x, y);
  2012.     if (curview != raw_cloud_at(x, y)) {
  2013.         set_cloud_view(side, x, y, raw_cloud_at(x, y));
  2014.         update = TRUE;
  2015.     }
  2016.     curview = cloud_bottom_view(side, x, y);
  2017.     if (curview != raw_cloud_bottom_at(x, y)) {
  2018.         set_cloud_bottom_view(side, x, y, raw_cloud_bottom_at(x, y));
  2019.         update = TRUE;
  2020.     }
  2021.     curview = cloud_height_view(side, x, y);
  2022.     if (curview != raw_cloud_height_at(x, y)) {
  2023.         set_cloud_height_view(side, x, y, raw_cloud_height_at(x, y));
  2024.         update = TRUE;
  2025.     }
  2026.     /* Even if the data didn't change, our information is
  2027.        now up-to-date. */
  2028.     if (!g_see_weather_always())
  2029.       set_cloud_view_date(side, x, y, g_turn());
  2030.     /* Only need one date for the three layers of view data. */
  2031.     }
  2032.     if (winds_defined()) {
  2033.     curview = wind_view(side, x, y);
  2034.     if (curview != raw_wind_at(x, y)) {
  2035.         set_wind_view(side, x, y, raw_wind_at(x, y));
  2036.         update = TRUE;
  2037.     }
  2038.     /* Even if the data didn't change, our information is
  2039.        now up-to-date. */
  2040.     if (!g_see_weather_always())
  2041.       set_wind_view_date(side, x, y, g_turn());
  2042.     }
  2043.     return update;
  2044. }
  2045.  
  2046. /* A border has been seen if the cell on either side has been seen. */
  2047.  
  2048. int
  2049. seen_border(side, x, y, dir)
  2050. Side *side;
  2051. int x, y, dir;
  2052. {
  2053.     int x1, y1;
  2054.  
  2055.     if (side->see_all)
  2056.       return TRUE;
  2057.     if (terrain_view(side, x, y) != UNSEEN)
  2058.       return TRUE;
  2059.     if (point_in_dir(x, y, dir, &x1, &y1))
  2060.       if (terrain_view(side, x1, y1) != UNSEEN)
  2061.     return TRUE;
  2062.     return FALSE;
  2063. }
  2064.  
  2065. /* Make a printable identification of the given side. */
  2066.  
  2067. char *
  2068. side_desig(side)
  2069. Side *side;
  2070. {
  2071.     if (sidedesigbuf == NULL)
  2072.       sidedesigbuf = xmalloc(BUFSIZE);
  2073.     if (side != NULL) {
  2074.     sprintf(sidedesigbuf, "s%d (%s)", side_number(side), side_name(side));
  2075.     if (side->self_unit) {
  2076.         tprintf(sidedesigbuf, "(self is #%d)", side->self_unit->id);
  2077.     }
  2078.     } else {
  2079.     sprintf(sidedesigbuf, "nullside");
  2080.     }
  2081.     return sidedesigbuf;
  2082. }
  2083.  
  2084. /* Add a player into the list of players.  All values are defaults here. */
  2085.  
  2086. Player *
  2087. add_player()
  2088. {
  2089.     Player *player = (Player *) xmalloc(sizeof(Player));
  2090.  
  2091.     player->id = nextplayerid++;
  2092.     /* Note that all names and suchlike slots are NULL. */
  2093.     ++numplayers;
  2094.     /* Add this one to the end of the player list. */
  2095.     if (last_player == NULL) {
  2096.     playerlist = last_player = player;
  2097.     } else {
  2098.     last_player->next = player;
  2099.     last_player = player;
  2100.     }
  2101.     Dprintf("Added a player\n");
  2102.     return player;
  2103. }
  2104.  
  2105. Player *
  2106. find_player(n)
  2107. int n;
  2108. {
  2109.     Player *player;
  2110.  
  2111.     for_all_players(player) {
  2112.        if (player->id == n)
  2113.     return player;
  2114.     }
  2115.     return NULL;
  2116. }
  2117.  
  2118. /* Transform a player object into a regularized form. */
  2119.  
  2120. void
  2121. canonicalize_player(player)
  2122. Player *player;
  2123. {
  2124.     if (player == NULL)
  2125.       return;
  2126.     if (empty_string(player->displayname))
  2127.       player->displayname = NULL;
  2128.     if (empty_string(player->aitypename))
  2129.       player->aitypename = NULL;
  2130.     /* This seems like a logical place to canonicalize an AI type
  2131.        of "ai" into a specific type, but we don't necessarily know
  2132.        the best default until the game is closer to starting. */
  2133. }
  2134.  
  2135. /* Make a printable identification of the given player. */
  2136.  
  2137. char *
  2138. player_desig(player)
  2139. Player *player;
  2140. {
  2141.     if (playerdesigbuf == NULL)
  2142.       playerdesigbuf = xmalloc(BUFSIZE);
  2143.     if (player != NULL) {
  2144.     sprintf(playerdesigbuf, "%s,%s/%s@%s+%d",
  2145.         (player->name ? player->name : ""),
  2146.         (player->aitypename ? player->aitypename : ""),
  2147.         (player->configname ? player->configname : ""),
  2148.         (player->displayname ? player->displayname : ""),
  2149.         player->advantage);
  2150.     } else {
  2151.     sprintf(playerdesigbuf, "nullplayer");
  2152.     }
  2153.     return playerdesigbuf;
  2154. }
  2155.  
  2156. /* Doctrine handling. */
  2157.  
  2158. Doctrine *
  2159. new_doctrine(id)
  2160. int id;
  2161. {
  2162.     Doctrine *doctrine = (Doctrine *) xmalloc(sizeof(Doctrine));
  2163.  
  2164.     if (id <= 0)
  2165.       id = next_doctrine_id++;
  2166.     doctrine->id = id;
  2167.     /* Add the new doctrine to the end of the list of doctrines. */
  2168.     if (last_doctrine != NULL) {
  2169.     last_doctrine->next = doctrine;
  2170.     last_doctrine = doctrine;
  2171.     } else {
  2172.     doctrine_list = last_doctrine = doctrine;
  2173.     }
  2174.     return doctrine;
  2175. }
  2176.  
  2177. Doctrine *
  2178. find_doctrine_by_name(name)
  2179. char *name;
  2180. {
  2181.     Doctrine *doctrine;
  2182.  
  2183.     if (name == NULL)
  2184.       return NULL;
  2185.     for (doctrine = doctrine_list; doctrine != NULL; doctrine = doctrine->next) {
  2186.     if (doctrine->name != NULL && strcmp(name, doctrine->name) == 0)
  2187.       return doctrine;
  2188.     }
  2189.     return NULL;
  2190. }
  2191.  
  2192. Doctrine *
  2193. find_doctrine(id)
  2194. int id;
  2195. {
  2196.     Doctrine *doctrine;
  2197.  
  2198.     for (doctrine = doctrine_list; doctrine != NULL; doctrine = doctrine->next) {
  2199.     if (doctrine->id == id)
  2200.       return doctrine;
  2201.     }
  2202.     return NULL;
  2203. }
  2204.  
  2205. Doctrine *
  2206. clone_doctrine(olddoc)
  2207. Doctrine *olddoc;
  2208. {
  2209.     int tmpid;
  2210.     Doctrine *newdoc, *tmpnext;
  2211.  
  2212.     newdoc = new_doctrine(0);
  2213.     tmpid = newdoc->id;
  2214.     tmpnext = newdoc->next;
  2215.     memcpy(newdoc, olddoc, sizeof(Doctrine));
  2216.     newdoc->id = tmpid;
  2217.     if (newdoc->construction_run) {
  2218.     newdoc->construction_run =
  2219.       (short *) xmalloc (numutypes * sizeof(short));
  2220.     memcpy(newdoc->construction_run, olddoc->construction_run, numutypes * sizeof(short));
  2221.     }
  2222.     newdoc->next = tmpnext;
  2223.     return newdoc;
  2224. }
  2225.  
  2226. /* Standing order handling. */
  2227.  
  2228. StandingOrder *
  2229. new_standing_order()
  2230. {
  2231.     StandingOrder *sorder;
  2232.  
  2233.     sorder = (StandingOrder *) xmalloc(sizeof(StandingOrder));
  2234.     sorder->types = xmalloc(numutypes);
  2235.     return sorder;
  2236. }
  2237.  
  2238. int order_conds_match PARAMS ((StandingOrder *sorder, StandingOrder *sorder2));
  2239.  
  2240. void
  2241. add_standing_order(side, sorder, pos)
  2242. Side *side;
  2243. StandingOrder *sorder;
  2244. int pos;
  2245. {
  2246.     StandingOrder *sorder2;
  2247.  
  2248.     if (sorder->task == NULL) {
  2249.     if (side->orders == NULL) {
  2250.         /* No orders, so nothing to do. */
  2251.         return;
  2252.     } else if (order_conds_match(sorder, side->orders)) {
  2253.         /* Delete the first order in the list. */
  2254.         if (side->last_order == side->orders)
  2255.           side->last_order = side->orders->next;
  2256.         side->orders = side->orders->next;
  2257.     } else {
  2258.         for (sorder2 = side->orders; sorder2->next != NULL; sorder2 = sorder2->next) {
  2259.         if (order_conds_match(sorder, sorder2->next)) {
  2260.             if (side->last_order == sorder2->next)
  2261.               side->last_order = sorder2->next->next;
  2262.             sorder2->next = sorder2->next->next;
  2263.             return;
  2264.         }
  2265.         }
  2266.         /* If we're here, no match; might be user error, but can't be sure,
  2267.            so don't say anything. */
  2268.     }
  2269.     } else if (pos == 0) {
  2270.     sorder->next = side->orders;
  2271.     side->orders = sorder;
  2272.     if (side->last_order == NULL)
  2273.       side->last_order = sorder;
  2274.     } else if (side->last_order != NULL) {
  2275.     side->last_order->next = sorder;
  2276.     side->last_order = sorder;
  2277.     } else {
  2278.     side->orders = side->last_order = sorder;
  2279.     }
  2280. }
  2281.  
  2282. int
  2283. order_conds_match(sorder, sorder2)
  2284. StandingOrder *sorder, *sorder2;
  2285. {
  2286.     return (sorder->etype == sorder2->etype
  2287.         && sorder->a1 == sorder2->a1
  2288.         && sorder->a2 == sorder2->a2
  2289.         && sorder->a3 == sorder2->a3);
  2290. }
  2291.  
  2292. int
  2293. parse_standing_order(side, cmdstr)
  2294. Side *side;
  2295. char *cmdstr;
  2296. {
  2297.     StandingOrder *sorder;
  2298.  
  2299.     sorder = new_standing_order();
  2300.     cmdstr = parse_unit_types(side, cmdstr, sorder->types);
  2301.     if (cmdstr == NULL)
  2302.       return (-1);
  2303.     cmdstr = parse_order_cond(side, cmdstr, sorder);
  2304.     if (cmdstr == NULL)
  2305.       return (-2);
  2306.     cmdstr = parse_task(side, cmdstr, &(sorder->task));
  2307.     if (cmdstr == NULL)
  2308.       return (-3);
  2309.     add_standing_order(side, sorder, 0);
  2310.     return 0;
  2311. }
  2312.  
  2313. char *
  2314. parse_unit_types(side, str, utypevec)
  2315. Side *side;
  2316. char *str, *utypevec;
  2317. {
  2318.     char *arg, substr[BUFSIZE], *rest;
  2319.     int u;
  2320.  
  2321.     rest = get_next_arg(str, substr, &arg);
  2322.     u = utype_from_name(arg);
  2323.     if (u != NONUTYPE) {
  2324.     utypevec[u] = 1;
  2325.     } else if (strcmp(arg, "all") == 0) {
  2326.     for_all_unit_types(u)
  2327.       utypevec[u] = 1;
  2328.     } else {
  2329.     notify(side, "Unit type \"%s\" not recognized", arg);
  2330.     return NULL;
  2331.     }
  2332.     return rest;
  2333. }
  2334.  
  2335. char *
  2336. parse_order_cond(side, str, sorder)
  2337. Side *side;
  2338. char *str;
  2339. StandingOrder *sorder;
  2340. {
  2341.     int x = 0, y = 0, dist = 0;
  2342.     char *arg, *arg2, substr[BUFSIZE], *rest;
  2343.     Unit *unit;
  2344.  
  2345.     rest = get_next_arg(str, substr, &arg);
  2346.     if (strcmp(arg, "at") == 0 || strcmp(arg, "@") == 0) {
  2347.     sorder->etype = 1;
  2348.     } else if (strcmp(arg, "in") == 0) {
  2349.     sorder->etype = 2;
  2350.     } else if (strcmp(arg, "within") == 0 || strcmp(arg, "near") == 0) {
  2351.     sorder->etype = 3;
  2352.     } else {
  2353.     notify(side, "Condition type \"%s\" not recognized", arg);
  2354.     return NULL;
  2355.     }
  2356.     if (sorder->etype == 3) {
  2357.     rest = get_next_arg(rest, substr, &arg);
  2358.     dist = strtol(arg, &arg2, 10);
  2359.     sorder->a3 = dist;
  2360.     }
  2361.     rest = get_next_arg(rest, substr, &arg);
  2362.     x = strtol(arg, &arg2, 10);
  2363.     if (arg != arg2 && *arg2 == ',') {
  2364.     y = strtol(arg2 + 1, &arg, 10);
  2365.     sorder->a1 = x;  sorder->a2 = y;
  2366.     return rest;
  2367.     } else if ((unit = find_unit_by_name(arg)) != NULL) {
  2368.     if (sorder->etype == 1 || sorder->etype == 3) {
  2369.         sorder->a1 = x;  sorder->a2 = y;
  2370.     } else if (sorder->etype == 2) {
  2371.         sorder->a1 = unit->id;
  2372.     } else {
  2373.         return NULL;
  2374.     }
  2375.     return rest;
  2376.     } else {
  2377.     notify(side, "Condition argument \"%s\" not recognized", arg);
  2378.     return NULL;
  2379.     }
  2380. }
  2381.  
  2382. /* Collect the next whitespace-separated argument. */
  2383.  
  2384. char *
  2385. get_next_arg(str, buf, rsltp)
  2386. char *str, *buf, **rsltp;
  2387. {
  2388.     char *p;
  2389.  
  2390.     strcpy(buf, str);
  2391.     p = buf;
  2392.     /* Skip past any leading whitespace. */
  2393.     while (isspace(*p))
  2394.       ++p;
  2395.     if (*p == '"') {
  2396.     ++p;
  2397.     *rsltp = p;
  2398.     while (*p != '"' && *p != '\0')
  2399.       ++p;
  2400.     *p = '\0';
  2401.     /* Increment so later scanning looks past the closing quote. */ 
  2402.     ++p;
  2403.     } else {
  2404.     *rsltp = p;
  2405.     while (!isspace(*p) && *p != '\0')
  2406.       ++p;
  2407.     *p = '\0';
  2408.     }
  2409.     return str + (p - buf);
  2410. }
  2411.  
  2412. /* Agreement handling here for now. */
  2413.  
  2414. Agreement *agreementlist = NULL;
  2415.  
  2416. Agreement *lastagreement;
  2417.  
  2418. int numagreements = 0;
  2419.  
  2420. char *agreementdesigbuf;
  2421.  
  2422. void
  2423. init_agreements()
  2424. {
  2425.     agreementlist = lastagreement = NULL;
  2426.     numagreements = 0;
  2427. }
  2428.  
  2429. Agreement *
  2430. create_agreement(id)
  2431. int id;
  2432. {
  2433.     Agreement *ag = (Agreement *) xmalloc(sizeof(Agreement));
  2434.  
  2435.     ag->id = id;
  2436.     ag->terms = lispnil;
  2437.     ag->next = NULL;
  2438.     if (agreementlist != NULL) {
  2439.     lastagreement->next = ag;
  2440.     } else {
  2441.     agreementlist = lastagreement = ag;
  2442.     }
  2443.     ++numagreements;
  2444.     return ag;
  2445. }
  2446.  
  2447. char *
  2448. agreement_desig(ag)
  2449. Agreement *ag;
  2450. {
  2451.     if (agreementdesigbuf == NULL)
  2452.       agreementdesigbuf = xmalloc(BUFSIZE);
  2453.     sprintf(agreementdesigbuf, "<ag %s %s %s>",
  2454.         (ag->typename ? ag->typename : "(null)"),
  2455.         (ag->name ? ag->name : "(null)"),
  2456.         (ag->terms == lispnil ? "(no terms)" : "...terms..."));
  2457.     return agreementdesigbuf;
  2458. }
  2459.  
  2460. #ifdef DESIGNERS
  2461.  
  2462. static void paint_view_1 PARAMS ((int x, int y));
  2463.  
  2464. static int tmptview;
  2465. static int tmpuview;
  2466.  
  2467. /* Paint the side's view with given values. */
  2468.  
  2469. void
  2470. paint_view(side, x, y, r, tview, uview)
  2471. Side *side;
  2472. int x, y, r, tview, uview;
  2473. {
  2474.     tmpside = side;
  2475.     tmptview = tview;
  2476.     tmpuview = uview;
  2477.     apply_to_area_plus_edge(x, y, r, paint_view_1);
  2478. }
  2479.  
  2480. static void
  2481. paint_view_1(x, y)
  2482. int x, y;
  2483. {
  2484.     int oldtview = terrain_view(tmpside, x, y);
  2485.     int olduview = unit_view(tmpside, x, y);
  2486.  
  2487.     if (oldtview != tmptview || olduview != tmpuview) {
  2488.     set_terrain_view(tmpside, x, y, tmptview);
  2489.     set_unit_view(tmpside, x, y, tmpuview);
  2490.     see_exact(tmpside, x, y);
  2491.     }
  2492. }
  2493.  
  2494. #endif /* DESIGNERS */
  2495.